from datetime import datetime
from RPIControl import *
import json
from Lib.SerialPort import *
from Lib.RelayControl import *
from Lib.DataRealtimeStability import *
from Lib.max31865 import *
from Lib.Utils import *
from Lib.PIDServer import *
from Lib.Borad75 import *
from SqlData.DataEntity import *
from SqlData.Business import *
import time
from threading import Lock
import threading
import RPi.GPIO as GPIO
import uuid
import os

relayControl = None
pidServer = None
borad75=None
currentTempTxt1 = None
currentTempTxt2 = None
currentTempTxt3 = None
startExperimentStepMark = True
experimentType=0
comFlag = False
pidTem=0
cee=0
czhi=75.0
serverTimeDiff=0;

tempStabilty1=None
tempStabilty2=None
tempStabilty3=None

try:
    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BCM)
    #蜂鸣器
    GPIO.setup(25, GPIO.OUT)
    #微动开关
    GPIO.setup(18, GPIO.IN)
    #浮球液位传感器
    GPIO.setup(17, GPIO.IN)

    #max = max31865(5, 9, 10, 11, 6)
except :
    pass
#设备状态
statusCode = 0
thread = None
thread_lock = Lock()
stableTempStr = '0'
bindex = 0

def temp_background_thread():
    global bindex
    bindex = 0
    #试样温度
    temp1 = '0'
    #腔体温度（主）
    temp2 = '0'
    #腔体温度（辅 PID）
    temp3 = '0'
    #试样稳定温度
    while startExperimentStepMark:
        kg = ''
        fq = ''
        try:
            global bindex
            bindex+=1
            if(bindex==1 or abs(borad75.temp1-float(temp1))<6.0):
                if(borad75.temp1<78 and tempStabilty1!=None):
                    temp1= str(tempStabilty1.AppendData(borad75.temp1))
                    temp3= str(tempStabilty2.AppendData(borad75.temp2))
                else:
                    temp1=str(borad75.temp1)
                    temp3=str(borad75.temp2)

            global pidTem
            pidTem=pidServer.temp
            if(pidTem!=None and pidTem!=0.29 and (bindex==1 or abs(pidTem-float(temp2))<6.0)):
                if(tempStabilty3!=None):
                    temp2= str(tempStabilty3.AppendData(pidTem))
                else:
                    temp2 = str(pidTem)
            #currentTempTxt1.writelines("{0} {1}
            #{2}\n".format(datetime.datetime.now().strftime('%Y-%m-%d
            #%H:%M:%S'),temp1, temp2))

            t = time.time()
            sjc = (int(t)) * 1000+serverTimeDiff
            kg = str(GPIO.input(18))
            fq = str(GPIO.input(17))
            if(bindex == 1):
                currentTempTxt1.writelines("[[{0},{1}]".format(sjc,temp1))
                currentTempTxt2.writelines("[[{0},{1}]".format(sjc,temp2))
                currentTempTxt3.writelines("[[{0},{1}]".format(sjc,temp3))
            else:
                currentTempTxt1.writelines(",[{0},{1}]".format(sjc,temp1))
                currentTempTxt2.writelines(",[{0},{1}]".format(sjc,temp2))
                currentTempTxt3.writelines(",[{0},{1}]".format(sjc,temp3))
            currentTempTxt1.flush()
            currentTempTxt2.flush()
            currentTempTxt3.flush()
        except Exception as e :
            pass
            #socketio.emit('server_temp',str(e),namespace='/temp')
        socketio.emit('server_temp', temp1 + "," + temp2 + "," + temp3 + "," + kg + "," + fq + ',' + stableTempStr,namespace='/temp')
        time.sleep(1)
    global thread
    thread = None

@app.route('/')
@app.route('/index')
def index():
    return "树莓派接口服务已经运行"

@app.route('/status')
def status():
    return str(statusCode)

@app.route('/getMacAddress')
def getMacAddress():
    mac = uuid.UUID(int = uuid.getnode()).hex[-12:]
    return ":".join([mac[e:e + 2] for e in range(0,11,2)])

@socketio.on('connect', namespace='/temp')
def socketTemp():
    global thread
    with thread_lock:
        if thread is None:
            thread = socketio.start_background_task(target=temp_background_thread)

@app.route('/userLogin')
def userLogin():
    user = BllUser().login(request.args["userName"],request.args["userPwd"])
    if(user is None):
        return Utils.ResultData(0,"用户名或密码错误！")
    else:
        return Utils.ResultData(1,"登录成功！",user)

#新增试验接口
@app.route('/insertExperiment')
def insertExperiment():
    experiment_id = str(Utils.UUID())
    global experimentType
    experimentType=int(request.args["experiment_type"])
    BllExperiment().insertExperiment(experiment_id,int(request.args["experiment_type"]),request.args["material_name"],float(request.args["set_temp"]),request.args["description"],request.args["user_id"],request.args["user_name"])
    return experiment_id

#更新试验接口
@app.route('/updateExperiment')
def updateExperiment():
    experiment_id = request.args["experiment_id"]
    total_count = int(request.args["total_count"])
    result = request.args["result"]
    BllExperiment().updateExperiment(experiment_id,0,total_count,result)
    return '1'

#新增试验步骤接口
@app.route('/insertExperimentStep')
def insertExperimentStep():
    try:
        global czhi
        if(GPIO.input(18)):
            return 'NOTCLOSE'
        experiment_id = request.args["experiment_id"]
        czhi= round(float(request.args["sywd"]),2)
        experiment_step_id = str(Utils.UUID())
        pidServer.setTem(czhi)
        pidServer.open()
        relayControl.motor(True)
        relayControl.run(True)

        t2 = threading.Thread(target=startWarn)
        t2.start()

        temp = 0
        try:
            temp = round(float(((encodestr.split(','))[0]).split(':')[1]),3) 
        except :
            pass
        t = time.time()
        start_time_stamp = (int(request.args["start_time_stamp"]))
        global serverTimeDiff
        serverTimeDiff =start_time_stamp- (int(t)+10) * 1000
        time_local = time.localtime((start_time_stamp / 1000))
        BllExperimentStep().insertExperimentStep(experiment_step_id,experiment_id,time.strftime("%Y-%m-%d %H:%M:%S",time_local),temp)
        stepIndex = len(BllExperimentStep().findList(EntityExperimentStep.experiment_id == experiment_id).all())
        tempPath = '/home/pi/Downloads/RPIControl/Resource/ExperimentTemp/{0}'.format(experiment_id)
        Utils.mkdir(tempPath)
        global currentTempTxt1
        currentTempTxt1 = open('{0}/{1}_1.json'.format(tempPath,stepIndex),'w+')
        global currentTempTxt2
        currentTempTxt2 = open('{0}/{1}_2.json'.format(tempPath,stepIndex),'w+')
        global currentTempTxt3
        currentTempTxt3 = open('{0}/{1}_3.json'.format(tempPath,stepIndex),'w+')

        global startExperimentStepMark
        startExperimentStepMark = True
        global stableTempStr
        stableTempStr='0'
        t3 = threading.Thread(target=experimentProcess,args=(experimentType,))
        t3.start()
        return experiment_step_id
    except Exception as e:
        relayControl.motor(False)
        relayControl.light(False)
        relayControl.warn(False)
        relayControl.run(False)
        GPIO.output(25, GPIO.LOW)
        pidServer.close()
        return str('error:'+e)
    #return jsonify([experiment_step_id,start_time_stamp])

#停止试验接口
@app.route('/stopExperimentStep')
def stopExperimentStep():
    try:
        global startExperimentStepMark
        startExperimentStepMark=False
        time.sleep(0.5)
        relayControl.motor(False)
        relayControl.light(False)
        relayControl.warn(False)
        relayControl.run(False)
        GPIO.output(25, GPIO.LOW)
        currentTempTxt1.writelines("]")
        currentTempTxt2.writelines("]")
        currentTempTxt3.writelines("]")
        currentTempTxt1.flush()
        currentTempTxt2.flush()
        currentTempTxt3.flush()
        currentTempTxt1.close()
        currentTempTxt2.close()
        currentTempTxt3.close()
        
        experiment_step_id = request.args["experiment_step_id"]
        stot_time_stamp = (int(request.args["stot_time_stamp"]))
        tempStatus = int(request.args["tempStatus"])
        sampleStatus = int(request.args["sampleStatus"])
        isOpenBeep = int(request.args["isOpenBeep"])
        time_cost = (int(request.args["time_cost"]))
        time_local = time.localtime(stot_time_stamp / 1000)
        BllExperimentStep().updateExperimentStep(experiment_step_id,time.strftime("%Y-%m-%d %H:%M:%S",time_local),time_cost,tempStatus,sampleStatus)
        global bindex
        bindex = 0
        if(isOpenBeep == 1):
            GPIO.output(25, GPIO.HIGH)
            relayControl.warn(True)
        pidServer.close()
    except Exception as e :
        return str(e)
    return '1'

@app.route('/openWarn')
def openWarn():
     GPIO.output(25, GPIO.HIGH)
     relayControl.warn(True)
     return '1'

@app.route('/openBeep')
def openBeep():
     GPIO.output(25, GPIO.HIGH)
     relayControl.abnormal(True)
     relayControl.warn(True)
     return '1'

@app.route('/closeBeep')
def closeBeep():
     GPIO.output(25, GPIO.LOW)
     relayControl.abnormal(False)
     relayControl.warn(False)
     return '1'

@app.route('/openLight')
def openLight():
     relayControl.light(True)
     return '1'

@app.route('/closeLight')
def closeLight():
     relayControl.light(False)
     return '1'

@app.route('/openMotor')
def openMotor():
     relayControl.motor(True)
     return '1'

@app.route('/closeMotor')
def closeMotor():
     relayControl.motor(False)
     return '1'

@app.route('/getExperimentInfo')
def getExperimentInfo():
    experiment_id = request.args["experiment_id"]
    return Utils.ResultData(1,"获取成功！",BllExperiment().getExperimentAllInfo(experiment_id))


#获取试验列表接口
@app.route('/getExperimentList')
def getExperimentList():
    searchValue = request.args["searchValue"]
    list = BllExperiment().getExperimentList().filter(EntityExperiment.material_name.like('%' + searchValue + '%')).order_by(EntityExperiment.start_time.desc()).all()
    return Utils.ResultData(1,"获取成功！",list)

#获取用户列表接口
@app.route('/getUserList')
def getUserList():
    searchValue = request.args["searchValue"]
    list = BllUser().getUserList().filter(or_(EntityUser.user_name.like('%' + searchValue + '%'),EntityUser.real_name.like('%' + searchValue + '%'))).all()
    return Utils.ResultData(1,"获取成功！",list)

#删除试验信息接口
@app.route('/deleteExperiment')
def deleteExperiment():
    experiment_id = request.args["experiment_id"]
    BllExperiment().delete(EntityExperiment.experiment_id == experiment_id)
    return Utils.ResultData(1,"删除成功！")

#通讯
@app.route('/com')
def com():
    global comFlag
    comFlag = True
    return '1'

#获取用户详情信息接口
@app.route('/getUserInfo')
def getUserInfo():
    userId = request.args["userId"]
    entity = BllUser().getUserInfo(userId)
    return Utils.ResultData(1,"获取成功！",entity)

#修改用户密码接口
@app.route('/updateUserPassword')
def updateUserPassword():
    userId= request.args["userId"]
    userPwd=request.args["userPwd"]
    entity = BllUser().getUserInfo(userId)
    entity.user_pwd = Utils.MD5(userPwd)
    BllUser().update(entity)
    return Utils.ResultData(1,"修改成功！",entity)

#删除用户接口
@app.route('/deleteUser')
def deleteUser():
    userId= request.args["userId"]
    BllUser().delete(EntityUser.user_id == userId)
    return Utils.ResultData(1,"删除成功！")

#保存用户信息接口
@app.route('/saveUser')
def saveUser():
    userId = request.args["userId"]
    userName = request.args["userName"]
    realName = request.args["realName"]
    userSex = int(request.args["userSex"])
    userRole = int(request.args["userRole"])
    userPhone = request.args["userPhone"]
    remark = request.args["remark"]
    entity = EntityUser()
    if(userId == "0"):
        entity.user_id = str(Utils.UUID())
        #默认用户密码“000000”
        entity.user_pwd = Utils.MD5("000000")
    else:
        entity = BllUser().findEntity(userId)
    entity.user_name = userName
    entity.real_name = realName
    entity.user_sex = userSex
    entity.user_role = userRole
    entity.user_phone = userPhone
    entity.remark = remark
    if(userId == "0"):
        #新增用户
        BllUser().insert(entity)
    else:
        #更新用户
        BllUser().update(entity)

    return Utils.ResultData(1,"保存成功！")

@app.route('/set')
def set():
    global startExperimentStepMark
    startExperimentStepMark = True
    return '1'
@app.route('/get')
def get():
    return str(startExperimentStepMark)

#新增试验接口
@app.route('/get1')
def get1():
    return str(bindex)

#新增试验接口
@app.route('/get2')
def get2():
    return str(pidServer.getStableTem())

#新增试验接口
@app.route('/get3')
def get3():
    try:
        return str(borad75.getStableTemp1())
    except Exception as e :
        return str(e)
    

#新增试验接口
@app.route('/get4')
def get4():
    return str(pidServer.listTem)

#新增试验接口
@app.route('/get5')
def get5():
    return str(borad75.listTemp1)

#新增试验接口
@app.route('/get6')
def get6():
    return stableTempStr

#新增试验接口
@app.route('/get7')
def get7():
    return str(experimentType)

#新增试验接口
@app.route('/get8')
def get8():
    return str(experimentType==1)

#新增试验接口
@app.route('/get9')
def get9():
    return str(borad75.temp1)

#新增试验接口
@app.route('/get10')
def get10():
    return str(borad75.temp1>=70)

#新增试验接口
@app.route('/get11')
def get11():
    return str(cee)

#新增试验接口
@app.route('/get12')
def get12():
    return str(pidServer.getStableTem()!=None and pidServer.getStableTem()>=75)

def comJianCe():
    global comFlag
    while True:
        relayControl.com(comFlag)
        comFlag = False
        time.sleep(3)

#开始试验时警报服务
def startWarn():
    relayControl.warn(True)
    time.sleep(5)
    relayControl.warn(False)

#试验控温流程
def experimentProcess(type):
    global stableTempStr
    global startExperimentStepMark
    global cee
    global czhi
    global tempStabilty1
    global tempStabilty2
    global tempStabilty3
    if(type==1):
        while startExperimentStepMark:
            if(pidServer.getStableTem()!=None and pidServer.getStableTem()>=czhi):
                stableTempStr='1'
                tempStabilty1=DataRealtimeStability(0.9)
                tempStabilty2=DataRealtimeStability(0.9)
                tempStabilty3=DataRealtimeStability(0.9)
                return
            time.sleep(0.3)

    else:
        cee=1
        while startExperimentStepMark:
            try:
                cee=2
                spidtemp=pidServer.getStableTem()
                if(spidtemp==None):
                    cee=9
                if(spidtemp!=None and spidtemp>=czhi):
                    tempStabilty3=DataRealtimeStability(0.9)
                    del borad75.listTemp1[:]
                    time.sleep(2)
                    cee=3
                    while True:
                        cee=4
                        time.sleep(0.3)
                        stableTemp=borad75.getStableTemp1()
                        vagTemp=borad75.getVagTemp1()
                        maxTemp=borad75.getMaxTemp1()
                        if((maxTemp!=None and maxTemp>=75) or (vagTemp!=None and vagTemp>=75) or (stableTemp!=None and stableTemp>=75)):
                            stableTempStr='1'
                            tempStabilty1=DataRealtimeStability(0.9)
                            tempStabilty2=DataRealtimeStability(0.9)
                            tempStabilty3=DataRealtimeStability(0.9)
                            return
                        if(stableTemp!=None and stableTemp<75):
                            tempStabilty3=None
                            czhi=round(czhi+(75-stableTemp)*0.7,1)
                            pidServer.setTem(czhi)
                            del pidServer.listTem
                            time.sleep(2)
                            break
                cee=5
                time.sleep(0.3)
            except :
                cee=9
                pass

try:
    relayControl = RelayControl()
    pidServer = PIDServer()
    borad75 = Borad75()
    relayControl.com(True)
except :
    pass


#t1 = threading.Thread(target=comJianCe)
#t1.start()
#@app.route('/init')
#def init():

    


     


